import { useArgs, useState } from "@storybook/preview-api"
import type { Meta, StoryObj } from "@storybook/react"
import { Button, Col, Divider, Flex, Form, Input, Row, Select } from "antd"

import { DataList, SFlex } from "@/components/common"
import { Toast } from "@/components/messages"
import storeTableItems from "@/pages/layout/getAllConfig"

type FieldType = {
	input: string
}

// More on how to set up stories at: https://storybook.js.org/docs/writing-stories#default-export
const meta = {
	title: "TableItems",
	parameters: {
		// Optional parameter to center the component in the Canvas. More info: https://storybook.js.org/docs/configure/story-layout
		layout: "fullscreen",
		docs: {
			source: {
				code: null
			}
		}
	},
	tags: ["autodocs"]

	// More on argTypes: https://storybook.js.org/docs/api/argtypes
	// Use `fn` to spy on the onClick arg, which will appear in the actions panel once invoked: https://storybook.js.org/docs/essentials/actions#action-args
} satisfies Meta<typeof DataList>

export default meta
type Story = StoryObj<typeof meta>

export const SearchColumns: Story = {
	name: "Table Columns Items Search",
	render: (args: any) => {
		const items = storeTableItems()

		const allOptions = Object.entries(items)
			.filter(([_, column]: any) => column.dataIndex)
			.map(([key, column]: any) => ({
				label: column.dataIndex + "-" + key,
				value: key,
				title: `${column?.title ?? ""}`,
				dataIndex: `${column?.dataIndex ?? ""}`,
				combine: `${column?.title ?? ""}${column?.label ?? ""}${column?.dataIndex ?? ""}`
			}))
		// const set = new Set()
		// const options = allOptions.filter(item => {
		// 	if (set.has(item.dataIndex)) {
		// 		return false
		// 	}
		// 	set.add(item.dataIndex)
		// 	return true
		// })

		const [columnNames, setColumnNames] = useState<string[]>([])
		const columns = [...columnNames.map(name => (items[name] ? { ...items[name], width: 50 } : {}))]

		const filterOption = (input: string, option?: { label: string; value: string; combine: string }) =>
			(option?.combine ?? "").toLowerCase().includes(input.replaceAll(" ", "").toLowerCase())

		return (
			<Flex vertical justify="flex-end" style={{ padding: "20px" }}>
				<h2>Table Columns Items Search</h2>
				<Select
					mode="multiple"
					style={{ width: "100%" }}
					options={allOptions}
					value={columnNames}
					onChange={setColumnNames}
					maxTagCount="responsive"
					placeholder="Search..."
					placement="topLeft"
					maxCount={5}
					filterOption={filterOption}
					optionRender={({ data }: any) => {
						return (
							<Flex gap="10px">
								<span>DataIndex: {data.label}</span>
								<span>/</span>
								<span>Title: {data.title}</span>
							</Flex>
						)
					}}
				/>
				<DataList {...args} columns={columns} />
			</Flex>
		)
	}
}

export const AutoColumnsGenerator: Story = {
	render: function Render() {
		const items = storeTableItems()
		// eslint-disable-next-line
		const [{ data }, updateArgs] = useArgs()

		const allOptions = Object.entries(items)
			.filter(([_, column]: any) => column.dataIndex)
			.map(([key, column]: any) => ({
				key: key,
				label: column.dataIndex,
				value: column.dataIndex,
				title: `${column?.title ?? ""}`,
				dataIndex: `${column?.dataIndex ?? ""}`,
				combine: `${key}${column?.title ?? ""}${column?.label ?? ""}${column?.dataIndex ?? ""}`
			}))

		const [insertions, setInsertions] = useState<string[]>([])
		const [missing, setMissing] = useState<string[]>([])

		const [submitForm] = Form.useForm<FieldType>()
		const submit = ({ input }: FieldType) => {
			try {
				JSON.parse(input)
			} catch (e) {
				Toast.error("Please input in JSON format")
				return
			}
			const keys = Object.keys(JSON.parse(input)).map(key => {
				if (key === "id") return "serialNumber"
				return key
			})

			const object = JSON.parse(input)
			updateArgs({
				data: Array.from({ length: 10 }, (_, k) => ({
					...object,
					id: k
				}))
			})

			const insertions = allOptions.map(item => item.value).filter(item => keys.includes(item))
			setInsertions(insertions)

			const differences = keys.filter(item => !insertions.includes(item))
			setMissing(differences)
		}
		const columns = [...insertions.map(name => (items[name] ? { ...items[name], width: 100 } : {}))].filter(
			(item: any) => !!item.dataIndex
		)

		return (
			<SFlex vertical justify="flex-end" style={{ padding: "20px" }}>
				<h2>Auto Columns Generator</h2>
				<Form
					initialValues={{
						input: JSON.stringify(
							{
								id: "1793919245498900482",
								newColumn1: "asd",
								newColumn2: "sdf",
								merchantId: "878597836592201781",
								userName: "intest02",
								updatedAt: "2024-05-24 16:17:32",
								updatedBy: "austin",
								windDescription: "long 2"
							},
							null,
							2
						)
					}}
					form={submitForm}
					labelCol={{ span: 4 }}
					wrapperCol={{ span: 16 }}
					style={{ maxWidth: "100%" }}
					onFinish={submit}
				>
					<Form.Item
						colon
						label="Input object record"
						name="input"
						rules={[{ required: true, message: "Please input object record!" }]}
					>
						<Input.TextArea rows={10} />
					</Form.Item>
					<Form.Item wrapperCol={{ offset: 8, span: 16 }}>
						<Button type="primary" htmlType="submit">
							Generate columns
						</Button>
					</Form.Item>
				</Form>
				<Divider />
				<Row>
					<Col span={12}>
						{insertions.length > 0 && (
							<pre>
								Existed columns:
								{JSON.stringify(
									allOptions
										.filter(item => insertions.includes(item.key) || insertions.includes(item.dataIndex))
										.map(item => `${item.dataIndex} - ${item.key}`),
									null,
									2
								)}
							</pre>
						)}
					</Col>
					<Col span={12}>
						{missing.length > 0 && (
							<pre>
								New dataIndex:
								{JSON.stringify(missing, null, 2)}
							</pre>
						)}
					</Col>
					<Col span={24}>
						{insertions.length > 0 && (
							<SFlex vertical>
								<Divider />
								<h4>Sample Data List</h4>
								<DataList data={data} rowKey={"id"} size="middle" bordered columns={columns} />
							</SFlex>
						)}
					</Col>
				</Row>
			</SFlex>
		)
	}
}
